package com.example.pool.httpTest.util;

// 异步HttpAsyncClient工具类
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.nio.reactor.IOReactorException;

public class HttpAsyncClientUtil {

    // 首先我们知道HTTP连接需要经过三次握手，四次挥手的过程，这是很耗费性能的；所以HTTP连接池帮助我们节省了这一步，提高了吞吐量。
    public static CloseableHttpAsyncClient getHttpAsyncClient() {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(10000) // 控制了连接建立的阶段，即从发起连接请求到连接建立完成的最大等待时间。
                .setSocketTimeout(20000) // 连接超时,连接建立时间,三次握手完成时间。
                .setConnectionRequestTimeout(50000) // 控制了从连接池中获取连接的阶段，即等待获取可用连接的最大等待时间。
                .build();
        //配置io线程
        IOReactorConfig ioReactorConfig = IOReactorConfig.custom().
//                setIoThreadCount(1)
                setIoThreadCount(Runtime.getRuntime().availableProcessors())
                .setSoKeepAlive(true)
                .build();
        //设置连接池大小
        ConnectingIOReactor ioReactor=null;
        try {
            ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
        } catch (IOReactorException e) {
            e.printStackTrace();
        }
        PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor);
        // 连接池中最大连接数
        connManager.setMaxTotal(1000);
//        connManager.setMaxTotal(10);
        // 分配给同一个route(路由)最大的并发连接数,route为运行环境机器到目标机器的一条线路,举例来说,我们使用HttpClient的实现来分别请求
        // www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route;
        // 这里如果和最大连接数设置的一样，则可能出现所有请求都被某个满服务占用的情况，所以这里尽量避免和MaxRouter设置的一样
        connManager.setDefaultMaxPerRoute(10);
        return HttpAsyncClients.custom().setConnectionManager(connManager)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }
}
